package org.kaleido.client;

import org.kaleido.client.activity.mapper.DataPanelActivityMapper;
import org.kaleido.client.place.AppPlaceHistoryMapper;
import org.kaleido.client.place.ListDataLogsPlace;
import org.kaleido.client.resources.KaleidoResources;
import org.kaleido.client.view.ApplicationLayoutView;
import org.kaleido.client.view.impl.ApplicationLayoutImpl;

import com.google.gwt.activity.shared.ActivityManager;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.place.shared.PlaceHistoryHandler;
import com.google.gwt.user.client.ui.RootLayoutPanel;

/**
 * Corazón de la aplicación, en donde se inicializa el mapper de actividades,
 * gestor del histórico, controller, eventBus, autenticación la declaración de
 * maejadores de eventos genéricos. Es donde se iniciliza la aplicación.
 */
public class KaleidoApplication {
    /**
     * Where components of the app converse by posting and monitoring events.
     */
    private final EventBus eventBus;

    /**
     * Owns the current {@link Place} in the app. A Place is the embodiment of
     * any bookmarkable state.
     */
    private final PlaceController placeController;

    /**
     * Manager de actividades que a partir del los place proporciona la
     * actividad a la que se redirecciona.
     */
    private final ActivityManager activityManager;

    /**
     * Maneja el histórico.
     */
    private final AppPlaceHistoryMapper historyMapper;

    /**
     * Maneja el histórico.
     */
    private final PlaceHistoryHandler historyHandler;

    /**
     * Client Factory.
     */
    private final ClientFactory clientFactory;

    /**
     * Constructor.
     */
    public KaleidoApplication(ClientFactory clientFactory, EventBus eventBus, ActivityManager activityManager,
            PlaceController placeController, AppPlaceHistoryMapper historyMapper, PlaceHistoryHandler historyHandler) {
        this.clientFactory = clientFactory;
        this.eventBus = eventBus;
        this.placeController = placeController;
        this.activityManager = activityManager;
        this.historyHandler = historyHandler;
        this.historyMapper = historyMapper;
    }

    /**
     * Inicializa los componentes de la aplicación y los manejadores de eventos
     * genéricos.
     */
    public void run(final RootLayoutPanel rootPanel) {
        KaleidoResources.INSTANCE.css().ensureInjected();
        ApplicationLayoutView appLayout = new ApplicationLayoutImpl(clientFactory, rootPanel);
        initializeActivityManagers(appLayout);
        initBrowserHistory(historyMapper, historyHandler, new ListDataLogsPlace());
    }

    private void initializeActivityManagers(ApplicationLayoutView appLayout) {
        DataPanelActivityMapper dataMapper = new DataPanelActivityMapper(clientFactory);
        ActivityManager dataActivityManager = new ActivityManager(dataMapper, eventBus);
        dataActivityManager.setDisplay(appLayout.getDataLogContainer());
    }

    /**
     * Initialize browser history / bookmarking. If LocalStorage is available,
     * use it to make the user's default location in the app the last one seen.
     */
    private void initBrowserHistory(final AppPlaceHistoryMapper historyMapper, PlaceHistoryHandler historyHandler,
            Place defaultPlace) {
        historyHandler.register(placeController, eventBus, defaultPlace);
        historyHandler.handleCurrentHistory();
    }
}
